/*
 * @Author: caiqi 
 * @Date: 2019-02-13 14:02:44 
 * @Last Modified by: caiqi
 * @Last Modified time: 2019-02-14 16:55:32
 * @Describe: 
  */

import api from "@/api/index";
import { checkBrowser } from "@/utils/check-browser";

const browser = new checkBrowser();
export class ListenError {
    constructor() {
        this.initError();
        this.initPromiseError();
        this.initConsoleError();
    }

    // ================================== 初始化全局错误监听 ================================== 
    initError() {
        window.addEventListener("error", e => {
            console.log(e, "e");

            let { message, filename, lineno, colno, error } = e;
            // 错误的堆栈
            let stack_info = "";
            // 是否有堆栈信息
            let is_stack = false;
            if (error.stack) {
                stack_info = error.stack;
                is_stack = true;
            } else {
                stack_info = error;
            }
            this.sendError("listen", {
                // 错误信息
                message,
                // 出错文件
                filename,
                // 出错行号
                line: lineno,
                // 出错列号
                column: colno,
                // 错误堆栈
                stack_info,
                // 是否有堆栈信息
                is_stack
            });
        });
    }

    // ================================== 初始化 promise 错误 监听 ================================== 
    async initPromiseError() {
        window.addEventListener("unhandledrejection", event => {
            event.preventDefault();
            const _message = event.reason.stack
            this.sendError('promise', { stack_info: _message })
        });
    }

    // ================================== 劫持console.error 错误 ================================== 
    initConsoleError() {
        let consoleError = window.console.error;
        const self = this;
        window.console.error = function () {
            let errorArray = [];
            Array.prototype.slice.apply(arguments).forEach(item => {
                consoleError(item)
                if (item.stack) {
                    errorArray.push({
                        stack_info: item.stack,
                        is_stack: true
                    });
                } else {
                    errorArray.push({
                        stack_info: item,
                        is_stack: false
                    });
                }
            });
            if (errorArray.length == 1) {
                self.sendError("print", errorArray[0]);
            } else {
                self.sendError("print", errorArray);
            }

            consoleError.apply(window, arguments);
        };
    }

    // ================================== 捕获vue全局error 错误 ================================== 
    errorVueHandler(err, vm, info) {
        // handle error
        // `info` 是 Vue 特定的错误信息，比如错误所在的生命周期钩子
        // 只在 2.2.0+ 可用

        window.vueVm = vm;
        // const print = new Print()

        // print.printDebug(window.vm, "vue_error_vm");
        let params = {};

        if (err.stack) {
            params = {
                stack_info: err.stack,
                is_stack: true
            };
        } else {
            params = {
                stack_info: err,
                is_stack: false
            };
        }
        params.vueInfo = info;

        window.sendError("vue_handler", params);
    }

    // ================================== 上传错误 ================================== 
    async sendError(error_type, error_data) {
        const errorData = {
            type: error_type,
            info: error_data,
            url: window.location.href,
            os: browser.getOsInfo(),
            brower: browser.getBrowserInfo()
        }
        // console.log('--------------------')
        // console.log(errorData)
        // console.log('--------------------')

        await api.sendError(errorData);
    }




}
